using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Chat.Backend.Services.Push
{
    /// <summary>
    /// 推送通知服务 - 负责向用户发送推送通知
    /// 转换自Java代码的push模块
    /// </summary>
    public class PushService : IPushService
    {
        private readonly ILogger<PushService> _logger;
        private readonly IUserService _userService;
        private readonly PushSettings _pushSettings;
        
        // 推送提供商
        private readonly Dictionary<string, IPushProvider> _pushProviders = new Dictionary<string, IPushProvider>();

        /// <summary>
        /// 构造函数
        /// </summary>
        public PushService(
            ILogger<PushService> logger,
            IUserService userService,
            IOptions<PushSettings> pushSettings,
            IEnumerable<IPushProvider> pushProviders)
        {
            _logger = logger;
            _userService = userService;
            _pushSettings = pushSettings.Value;
            
            // 注册推送提供商
            foreach (var provider in pushProviders)
            {
                _pushProviders[provider.ProviderName] = provider;
            }
        }

        /// <summary>
        /// 发送聊天消息推送通知
        /// </summary>
        public async Task SendChatMessagePushAsync(string userId, string title, string body, Dictionary<string, string> data)
        {
            try
            {
                // 获取用户信息
                var user = await _userService.GetUserByIdAsync(userId);
                if (user == null)
                {
                    _logger.LogWarning($"用户不存在: {userId}");
                    return;
                }
                
                // 检查用户是否在线，如果在线则不发送推送
                var isUserOnline = await _userService.IsUserOnlineAsync(userId);
                if (isUserOnline && !_pushSettings.PushToOnlineUsers)
                {
                    _logger.LogInformation($"用户在线，不发送推送: {userId}");
                    return;
                }
                
                // 获取用户的设备信息
                var devices = await _userService.GetUserDevicesAsync(userId);
                if (devices.Count == 0)
                {
                    _logger.LogInformation($"用户没有注册设备: {userId}");
                    return;
                }
                
                // 准备推送数据
                var pushData = new Dictionary<string, string>(data);
                pushData["type"] = "chat_message";
                
                // 为每个设备发送推送
                foreach (var device in devices)
                {
                    // 检查设备是否有效
                    if (string.IsNullOrEmpty(device.PushToken) || string.IsNullOrEmpty(device.PushProvider))
                    {
                        continue;
                    }
                    
                    // 获取对应的推送提供商
                    if (!_pushProviders.TryGetValue(device.PushProvider, out var provider))
                    {
                        _logger.LogWarning($"未知的推送提供商: {device.PushProvider}");
                        continue;
                    }
                    
                    // 创建推送请求
                    var request = new PushRequest
                    {
                        Token = device.PushToken,
                        Title = title,
                        Body = body,
                        Data = pushData,
                        Priority = PushPriority.High,
                        Sound = "default",
                        Badge = 1,
                        TimeToLive = 86400 // 1天
                    };
                    
                    // 发送推送
                    await provider.SendPushAsync(request);
                    
                    _logger.LogInformation($"发送聊天消息推送到用户 {userId} 的设备 {device.DeviceId}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"发送聊天消息推送失败: {userId}");
            }
        }

        /// <summary>
        /// 发送通话推送通知
        /// </summary>
        public async Task SendCallPushNotificationAsync(string userId, string title, string body, Dictionary<string, string> data)
        {
            try
            {
                // 获取用户信息
                var user = await _userService.GetUserByIdAsync(userId);
                if (user == null)
                {
                    _logger.LogWarning($"用户不存在: {userId}");
                    return;
                }
                
                // 获取用户的设备信息
                var devices = await _userService.GetUserDevicesAsync(userId);
                if (devices.Count == 0)
                {
                    _logger.LogInformation($"用户没有注册设备: {userId}");
                    return;
                }
                
                // 准备推送数据
                var pushData = new Dictionary<string, string>(data);
                pushData["type"] = "call";
                
                // 为每个设备发送推送
                foreach (var device in devices)
                {
                    // 检查设备是否有效
                    if (string.IsNullOrEmpty(device.PushToken) || string.IsNullOrEmpty(device.PushProvider))
                    {
                        continue;
                    }
                    
                    // 获取对应的推送提供商
                    if (!_pushProviders.TryGetValue(device.PushProvider, out var provider))
                    {
                        _logger.LogWarning($"未知的推送提供商: {device.PushProvider}");
                        continue;
                    }
                    
                    // 创建推送请求
                    var request = new PushRequest
                    {
                        Token = device.PushToken,
                        Title = title,
                        Body = body,
                        Data = pushData,
                        Priority = PushPriority.High,
                        Sound = "ringtone.wav", // 特殊的铃声
                        TimeToLive = 30, // 30秒，通话推送的有效期较短
                        MutableContent = true, // 允许iOS客户端修改通知内容
                        Category = "call" // iOS通知类别，用于显示特殊的操作按钮
                    };
                    
                    // 发送推送
                    await provider.SendPushAsync(request);
                    
                    _logger.LogInformation($"发送通话推送到用户 {userId} 的设备 {device.DeviceId}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"发送通话推送失败: {userId}");
            }
        }

        /// <summary>
        /// 注册设备推送令牌
        /// </summary>
        public async Task RegisterDeviceTokenAsync(string userId, string deviceId, string pushToken, string pushProvider, string deviceModel)
        {
            try
            {
                // 验证推送提供商是否支持
                if (!_pushProviders.ContainsKey(pushProvider))
                {
                    throw new ArgumentException($"不支持的推送提供商: {pushProvider}");
                }
                
                // 创建或更新设备信息
                var device = new UserDevice
                {
                    UserId = userId,
                    DeviceId = deviceId,
                    PushToken = pushToken,
                    PushProvider = pushProvider,
                    DeviceModel = deviceModel,
                    LastActiveTime = DateTime.UtcNow
                };
                
                // 保存设备信息
                await _userService.SaveUserDeviceAsync(device);
                
                _logger.LogInformation($"注册设备推送令牌: 用户 {userId}, 设备 {deviceId}, 提供商 {pushProvider}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"注册设备推送令牌失败: 用户 {userId}, 设备 {deviceId}");
                throw;
            }
        }

        /// <summary>
        /// 移除设备推送令牌
        /// </summary>
        public async Task UnregisterDeviceTokenAsync(string userId, string deviceId)
        {
            try
            {
                // 移除设备信息
                await _userService.RemoveUserDeviceAsync(userId, deviceId);
                
                _logger.LogInformation($"移除设备推送令牌: 用户 {userId}, 设备 {deviceId}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"移除设备推送令牌失败: 用户 {userId}, 设备 {deviceId}");
                throw;
            }
        }
    }

    /// <summary>
    /// 推送通知服务接口
    /// </summary>
    public interface IPushService
    {
        Task SendChatMessagePushAsync(string userId, string title, string body, Dictionary<string, string> data);
        Task SendCallPushNotificationAsync(string userId, string title, string body, Dictionary<string, string> data);
        Task RegisterDeviceTokenAsync(string userId, string deviceId, string pushToken, string pushProvider, string deviceModel);
        Task UnregisterDeviceTokenAsync(string userId, string deviceId);
    }
}